package cn.com.infcn.monitor.core;

import static cn.com.infcn.monitor.util.MonitorType.CPU;
import static cn.com.infcn.monitor.util.MonitorType.DIRECTORY;
import static cn.com.infcn.monitor.util.MonitorType.FILESYSTEM;
import static cn.com.infcn.monitor.util.MonitorType.HTTPREQUEST;
import static cn.com.infcn.monitor.util.MonitorType.HTTPSESSION;
import static cn.com.infcn.monitor.util.MonitorType.JVMCLASSLOADING;
import static cn.com.infcn.monitor.util.MonitorType.JVMCOMPILATION;
import static cn.com.infcn.monitor.util.MonitorType.JVMGARBAGECOLLECTOR;
import static cn.com.infcn.monitor.util.MonitorType.JVMMEMORY;
import static cn.com.infcn.monitor.util.MonitorType.JVMMEMORYMANAGER;
import static cn.com.infcn.monitor.util.MonitorType.JVMMEMORYPOOL;
import static cn.com.infcn.monitor.util.MonitorType.JVMOPERATINGSYSTEM;
import static cn.com.infcn.monitor.util.MonitorType.JVMRUNTIME;
import static cn.com.infcn.monitor.util.MonitorType.JVMTHREAD;
import static cn.com.infcn.monitor.util.MonitorType.NET;
import static cn.com.infcn.monitor.util.MonitorType.OS;
import static cn.com.infcn.monitor.util.MonitorType.SYSMEM;
import static cn.com.infcn.monitor.util.MonitorType.USER;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.Enumeration;
import java.util.List;
import java.util.Set;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

import org.apache.log4j.Logger;

import cn.com.infcn.monitor.bean.IFCCpu;
import cn.com.infcn.monitor.bean.IFCDirectory;
import cn.com.infcn.monitor.bean.IFCFileSystem;
import cn.com.infcn.monitor.bean.IFCHttpRequest;
import cn.com.infcn.monitor.bean.IFCHttpSession;
import cn.com.infcn.monitor.bean.IFCJVMClassLoading;
import cn.com.infcn.monitor.bean.IFCJVMCompilation;
import cn.com.infcn.monitor.bean.IFCJVMGarbageCollector;
import cn.com.infcn.monitor.bean.IFCJVMMemory;
import cn.com.infcn.monitor.bean.IFCJVMMemoryManager;
import cn.com.infcn.monitor.bean.IFCJVMMemoryPool;
import cn.com.infcn.monitor.bean.IFCJVMOperatingSystem;
import cn.com.infcn.monitor.bean.IFCJVMRuntime;
import cn.com.infcn.monitor.bean.IFCJVMThread;
import cn.com.infcn.monitor.bean.IFCMem;
import cn.com.infcn.monitor.bean.IFCNet;
import cn.com.infcn.monitor.bean.IFCOperatingSystem;
import cn.com.infcn.monitor.bean.IFCResponseBean;
import cn.com.infcn.monitor.bean.IFCUser;
import cn.com.infcn.monitor.task.BaseTask;
import cn.com.infcn.monitor.task.jvm.JVMClassLoadingTask;
import cn.com.infcn.monitor.task.jvm.JVMCompilationTask;
import cn.com.infcn.monitor.task.jvm.JVMGarbageCollectorTask;
import cn.com.infcn.monitor.task.jvm.JVMMemoryManagerTask;
import cn.com.infcn.monitor.task.jvm.JVMMemoryPoolTask;
import cn.com.infcn.monitor.task.jvm.JVMMemoryTask;
import cn.com.infcn.monitor.task.jvm.JVMOperatingSystemTask;
import cn.com.infcn.monitor.task.jvm.JVMRuntimeTask;
import cn.com.infcn.monitor.task.jvm.JVMThreadTask;
import cn.com.infcn.monitor.task.system.CpuTask;
import cn.com.infcn.monitor.task.system.DirectoryTask;
import cn.com.infcn.monitor.task.system.FileSystemTask;
import cn.com.infcn.monitor.task.system.NetTask;
import cn.com.infcn.monitor.task.system.OsTask;
import cn.com.infcn.monitor.task.system.SysMemTask;
import cn.com.infcn.monitor.task.system.UserTask;
import cn.com.infcn.monitor.task.web.HttpRequestTask;
import cn.com.infcn.monitor.task.web.HttpSessionTask;
import cn.com.infcn.monitor.util.IFCDateUtils;
import cn.com.infcn.monitor.util.IFCMonitorConstanst;
import cn.com.infcn.monitor.util.LibraryPath;

public class MonitorCore {

	private final static Logger LOGGER = Logger.getLogger(MonitorCore.class);

	/*static {
		System.out.println("-----------------init core----------------------");
		// 解压当前jar包的本地路径文件到根目录
		String jarPath = MonitorCore.class.getProtectionDomain().getCodeSource().getLocation().getPath();
		File jarFile = new File(jarPath);
		final String dirPath = jarFile.getParent();
		final int idx = dirPath.indexOf("WEB-INF");
		File f = null;
		if (jarPath.endsWith(".jar")) {
			JarFile jar = null;
			try {
				jar = new JarFile(jarFile);
				Enumeration<JarEntry> entries = jar.entries();
				while (entries.hasMoreElements()) {
					JarEntry entry = entries.nextElement();

					String name = entry.getName();
					
					if (name.endsWith(".so") || name.endsWith(".sl") || name.endsWith(".dylib") || name.endsWith(".dll")
							|| name.endsWith(".lib")) {
						f = new File(dirPath + File.separator + name);
					}else{
						//判断是否web项目，如果是，则解压html页面信息
						if(idx > 1){
							//静态页面在jar包中的目录名“ifcmonitor”
							//只解压ifcmonitor下面的文件，META-INF目录下的ifcmonitor不解压
							if(name.indexOf("ifcmonitor")==-1 || name.indexOf("META-INF")!=-1){
								continue;
							}
							
							f = new File(dirPath.substring(0, idx) + name);
						}else{
							continue;
						}
					}
					
					// 如果是目录，则直接进入下一个循环
					if (entry.isDirectory()) {
						if (!f.exists()){
							f.mkdirs();
						}
						continue;
					}
					InputStream in = null;
					OutputStream out = null;
					try {
						in = jar.getInputStream(entry);
						FileOutputStream fos = new FileOutputStream(f);
						out = new BufferedOutputStream(fos);
						byte[] buffer = new byte[2048];
						int nBytes = 0;
						while ((nBytes = in.read(buffer)) > 0) {
							out.write(buffer, 0, nBytes);
						}
					} catch (IOException ioe) {
						throw ioe;
					} finally {
						try {
							if (out != null) {
								out.flush(); // 立刻写
								out.close();
							}
						} catch (IOException ioe) {
							throw ioe;
						} finally {
							if (in != null) {
								in.close();
							}
						}
					}

				}
			} catch (IOException e) {
				e.printStackTrace();
				LOGGER.error(e.getMessage());
			} finally {
				if (jar != null) {
					try {
						jar.close();
					} catch (IOException e) {
						e.printStackTrace();
						LOGGER.error(e.getMessage());
					}
				}
			}
			//加载类库路径（.so .sl .dll .dylib .lib）
			File libPath = new File(dirPath);
			LOGGER.info("add java.library.path " + libPath);
			LibraryPath.addDir(libPath.getAbsolutePath());
		}
	}*/
	
	static {
		System.out.println("-----------------init core----------------------");
		LOGGER.info("-----------------init core----------------------");
		// 解压当前jar包的本地路径文件到根目录
		String jarPath = MonitorCore.class.getProtectionDomain().getCodeSource().getLocation().getPath();
		File jarFile = new File(jarPath);
		File local = jarFile.getParentFile();
		if (jarPath.endsWith(".jar")) {
			JarFile jar = null;
			try {
				jar = new JarFile(jarFile);
				Enumeration<JarEntry> entries = jar.entries();
				while (entries.hasMoreElements()) {
					JarEntry entry = entries.nextElement();
					if (entry.isDirectory()) {
						continue;
					}

					String name = entry.getName();

					if (name.endsWith(".so") || name.endsWith(".sl") || name.endsWith(".dylib") || name.endsWith(".dll")
							|| name.endsWith(".lib")) {

						File outFile = new File(local, name);

						if (outFile.exists()) {
							continue;
						}


						InputStream in = null;
						FileOutputStream out = null;
						try {
							in = jar.getInputStream(entry);
							out = new FileOutputStream(outFile);
							byte[] buffer = new byte[2048];
							int nBytes = 0;
							while ((nBytes = in.read(buffer)) > 0) {
								out.write(buffer, 0, nBytes);
							}
						} catch (Exception e) {
							LOGGER.warn(e.getMessage(), e);
						} finally {
							if (in != null) {
								in.close();
							}
							if (out != null) {
								out.flush();
								out.close();
							}
						}

					}

				}
			} catch (IOException e) {
				LOGGER.warn(e.getMessage(), e);
			} finally {
				if (jar != null) {
					try {
						jar.close();
					} catch (IOException e) {
						LOGGER.warn(e.getMessage(), e);
					}
				}
			}

			LibraryPath.addDir(local.getAbsolutePath());
		}
	}
	
	@SuppressWarnings("unchecked")
	public static IFCResponseBean getIFCResponseBean(Set<String> types) throws Exception {
		IFCResponseBean result = new IFCResponseBean();
		result.setDate(IFCDateUtils.getDateStr(new Date(), "yyyyMMddHHmm"));
		BaseTask task = null;

		for (String t : types) {

			if (CPU.getName().equals(t)) {
				task = new CpuTask();
				result.setIfcCpus((List<IFCCpu>) task.execute());
			}

			if (SYSMEM.getName().equals(t)) {
				task = new SysMemTask();
				result.setIfcMem((IFCMem) task.execute());
			}

			if (OS.getName().equals(t)) {
				task = new OsTask();
				result.setIfcOperatingSystem((IFCOperatingSystem) task.execute());
			}

			if (USER.getName().equals(t)) {
				task = new UserTask();
				result.setIfcUsers((List<IFCUser>) task.execute());
			}

			if (FILESYSTEM.getName().equals(t)) {
				task = new FileSystemTask();
				result.setIfcFileSystems((List<IFCFileSystem>) task.execute());
			}

			if (NET.getName().equals(t)) {
				task = new NetTask();
				result.setIfcNets((List<IFCNet>) task.execute());
			}

			if (DIRECTORY.getName().equals(t)) {
				List<IFCDirectory> list = new ArrayList<IFCDirectory>();
				for (String path : IFCMonitorConstanst.dirPaths) {
					task = new DirectoryTask(path);
					IFCDirectory ifcDirectory = (IFCDirectory) task.execute();
					if (ifcDirectory != null) {
						list.add(ifcDirectory);
					}
					result.setIfcDirectorys(list);
				}
			}

			if (JVMCLASSLOADING.getName().equals(t)) {
				task = new JVMClassLoadingTask();
				result.setIfcJVMClassLoading((IFCJVMClassLoading) task.execute());
			}

			if (JVMCOMPILATION.getName().equals(t)) {
				task = new JVMCompilationTask();
				result.setIfcJVMCompilation((IFCJVMCompilation) task.execute());
			}

			if (JVMGARBAGECOLLECTOR.getName().equals(t)) {
				task = new JVMGarbageCollectorTask();
				result.setIfcJVMGarbageCollectors((List<IFCJVMGarbageCollector>) task.execute());
			}

			if (JVMMEMORYMANAGER.getName().equals(t)) {
				task = new JVMMemoryManagerTask();
				result.setIfcJVMMemoryManagers((List<IFCJVMMemoryManager>) task.execute());
			}

			if (JVMMEMORYPOOL.getName().equals(t)) {
				task = new JVMMemoryPoolTask();
				result.setIfcJVMMemoryPool((IFCJVMMemoryPool) task.execute());
			}

			if (JVMMEMORY.getName().equals(t)) {
				task = new JVMMemoryTask();
				result.setIfcJVMMemory((IFCJVMMemory) task.execute());
			}

			if (JVMOPERATINGSYSTEM.getName().equals(t)) {
				task = new JVMOperatingSystemTask();
				result.setIfcJVMOperatingSystem((IFCJVMOperatingSystem) task.execute());
			}

			if (JVMRUNTIME.getName().equals(t)) {
				task = new JVMRuntimeTask();
				result.setIfcJVMRuntime((IFCJVMRuntime) task.execute());
			}

			if (JVMTHREAD.getName().equals(t)) {
				task = new JVMThreadTask();
				result.setIfcJVMThread((IFCJVMThread) task.execute());
			}

			if (HTTPREQUEST.getName().equals(t)) {
				task = new HttpRequestTask();
				result.setIfcHttpRequest((IFCHttpRequest) task.execute());
			}

			if (HTTPSESSION.getName().equals(t)) {
				task = new HttpSessionTask();
				result.setIfcHttpSession((IFCHttpSession) task.execute());
			}
		}

		return result;
	}
}
